package com.pig4cloud.pig.ai.utils;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.pig4cloud.pig.ai.api.dto.CollectionMetadata;
import com.pig4cloud.pig.ai.api.dto.DataDto;
import com.pig4cloud.pig.ai.api.dto.FileDataDto;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.compress.utils.Lists;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.URL;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class AiUtils {
    private static String API_KEY;
    private static String SECRET_KEY;
    private static String TOKEN_URL;
    private static String BAIDU_URL;
    private static String ASR_URL;
    private static String TTS_URL;
    private static String FAST_KEY;
    private static String FAST_APPID;
    private static String FAST_URL;

    public static void setFastKey(String fastKey) {
        FAST_KEY = fastKey;
    }

    public static void setFastAppid(String fastAppid) {
        FAST_APPID = fastAppid;
    }

    public static void setFastUrl(String fastUrl) {
        FAST_URL = fastUrl;
    }

    public static void setApiKey(String apiKey) {
        API_KEY = apiKey;
    }

    public static void setSecretKey(String secretKey) {
        SECRET_KEY = secretKey;
    }

    public static void setTokenUrl(String tokenUrl) {
        TOKEN_URL = tokenUrl;
    }

    public static void setBaiduUrl(String baiduUrl) {
        BAIDU_URL = baiduUrl;
    }

    public static void setAsrUrl(String asrUrl) {
        ASR_URL = asrUrl;
    }

    public static void setTtsUrl(String ttsUrl) {
        TTS_URL = ttsUrl;
    }
    private static final OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder().connectTimeout(10, TimeUnit.SECONDS).connectionPool(new ConnectionPool(5,4,TimeUnit.SECONDS)).build();

    /**
    *百度大模型获取token
    */
    public String  getAccessToken() throws IOException {
        HttpClient httpClient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(TOKEN_URL+"?grant_type=client_credentials&client_id="+API_KEY+"&client_secret="+SECRET_KEY);
        httpPost.addHeader("Content-Type","application/json");
        HttpResponse response = httpClient.execute(httpPost);
        String result = null;
        String access_token=null;
        if (response != null) {
            HttpEntity entity = response.getEntity();
            result = EntityUtils.toString(entity, "utf-8");
            JSONObject pa = JSONObject.parseObject(result);
            access_token = pa.getString("access_token");
            System.out.println(access_token);
        }
        return access_token;
    }
	/**
	 *百度对话
	 */
    public  String talk(String text) throws IOException, InterruptedException {
        JSONObject arrObj=new JSONObject();
        arrObj.put("chatId",FAST_APPID);//appid
        arrObj.put("stream",false);
        arrObj.put("detail",false);
        JSONObject varObj=new JSONObject();
        arrObj.put("variables",varObj);
        varObj.put("uid","adsjfjjgf");
        varObj.put("name","张三");
        JSONObject userObj=new JSONObject();
        userObj.put("role","user");
        userObj.put("content",text);
        JSONArray jsonArray=new JSONArray();
        jsonArray.add(userObj);
        arrObj.put("messages",jsonArray);
        System.out.println("输入参数："+arrObj);
        MediaType mediaType = MediaType.parse("application/json");
        RequestBody body = RequestBody.create(mediaType, arrObj.toString());
        Request request = new Request.Builder()
                .url(FAST_URL+"/v1/chat/completions")
                .method("POST", body)
                .addHeader("Content-Type", "application/json")
                .addHeader("Authorization","Bearer "+FAST_KEY)
                .build();
        String result="";
        try {
            Response response = execute(request);
            String str = response.body().string();
            JSONObject pa = JSONObject.parseObject(str);
            String choices = pa.getString("choices");
            JSONArray objects = JSONArray.parseArray(choices);
            if (objects != null && objects.size() > 0) {
                JSONObject object = JSONObject.parseObject(objects.get(0).toString());
                String message = object.getString("message");
                System.out.println(message);
                JSONObject mobj = JSONObject.parseObject(message);
                System.out.println(mobj.getString("content"));
                result = mobj.getString("content");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }
	/**
	 *fast-gpt向导
	 */
    public  List<Object> guide(String text){
        String token = getToken();
        JSONObject arrObj=new JSONObject();
        JSONObject userObj=new JSONObject();
        userObj.put("role","user");
        userObj.put("content",text);
        JSONArray jsonArray=new JSONArray();
        jsonArray.add(userObj);
        arrObj.put("messages",jsonArray);
        System.out.println("输入参数："+arrObj);
        MediaType mediaType = MediaType.parse("application/json");
        RequestBody body = RequestBody.create(mediaType, arrObj.toString());
        Request request = new Request.Builder()
                .url(FAST_URL+"/core/ai/agent/createQuestionGuide")
                .method("POST", body)
                .addHeader("Content-Type", "application/json")
                .addHeader("token",token)
                .build();
        List<Object> list= Lists.newArrayList();
        try {
            Response response =execute(request);;
            String str=response.body().string();
            JSONObject pa = JSONObject.parseObject(str);
            System.out.println(pa.toJSONString());
            String choices=pa.getString("data");
            JSONArray objects = JSONArray.parseArray(choices);
            if(objects!=null){
                objects.forEach(arr->{
                    list.add(arr);
                });
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return list;
    }
	/**
	 *fast-gpt获取token
	 */
    public  String getToken(){
        JSONObject arrObj=new JSONObject();
        arrObj.put("username","root");
        arrObj.put("password","03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4");
        System.out.println("输入参数："+arrObj);
        MediaType mediaType = MediaType.parse("application/json");
        RequestBody body = RequestBody.create(mediaType, arrObj.toString());
        Request request = new Request.Builder()
                .url(FAST_URL+"/support/user/account/loginByPassword")
                .method("POST", body)
                .addHeader("Content-Type", "application/json")
                .build();
        String result="";
        try {
            Response response =execute(request);;
            String str=response.body().string();
            JSONObject pa = JSONObject.parseObject(str);
            System.out.println(pa.toJSONString());
            String choices=pa.getString("data");
            JSONObject objects = JSONObject.parseObject(choices);
            if(objects!=null){
                String message=objects.getString("token");
                System.out.println(message);
                result=message;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }
	/**
	 *fast-gpt创建知识库
	 */
	public  String create(String name,String intro){
		JSONObject arrObj=new JSONObject();
		arrObj.put("parentId",null);
		arrObj.put("type","dataset");
		arrObj.put("name",name);
	    arrObj.put("intro",intro);
		arrObj.put("avatar","/icon/logo.svg");
		arrObj.put("vectorModel","text-embedding-ada-002");
		arrObj.put("agentModel","gpt-3.5-turbo-16k");
		System.out.println("输入参数："+arrObj);
		MediaType mediaType = MediaType.parse("application/json");
		RequestBody body = RequestBody.create(mediaType, arrObj.toString());
		Request request = new Request.Builder()
				.url(FAST_URL+"/core/dataset/create")
				.method("POST", body)
				.addHeader("Content-Type", "application/json")
				.addHeader("Authorization","Bearer "+FAST_KEY)
				.build();
		String data="";
		try {
			Response response =execute(request);;
			String str=response.body().string();
			JSONObject pa = JSONObject.parseObject(str);
			String code=pa.getString("code");
			if(code.equals("200")){
				data=pa.getString("data");
				System.out.println(data);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return data;
	}
	/**
	 *fast-gpt知识库列表
	 */
	public  String list(){
		Request request = new Request.Builder()
				.url(FAST_URL+"/core/dataset/list?parentId=")
				.get()
				.addHeader("Authorization","Bearer "+FAST_KEY)
				.build();
		String data="";
		try {
			Response response =execute(request);;
			String str=response.body().string();
			JSONObject pa = JSONObject.parseObject(str);
			String code=pa.getString("code");
			if(code.equals("200")){
				data=pa.getString("data");
				System.out.println(data);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return data;
	}
	/**
	 *fast-gpt知识库详情
	 */
	public  String detail(String id){
		Request request = new Request.Builder()
				.url(FAST_URL+"/core/dataset/detail?id="+id)
				.get()
				.addHeader("Authorization","Bearer "+FAST_KEY)
				.build();
		String data="";
		try {
			Response response =execute(request);;
			String str=response.body().string();
			JSONObject pa = JSONObject.parseObject(str);
			String code=pa.getString("code");
			if(code.equals("200")){
				data=pa.getString("data");
				System.out.println(data);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return data;
	}
	/**
	 *fast-gpt删除知识库
	 */
	public  String delete(String id){
		Request request = new Request.Builder()
				.url(FAST_URL+"/core/dataset/delete?id="+id)
				.delete()
				.addHeader("Authorization","Bearer "+FAST_KEY)
				.build();
		String code="";
		try {
			Response response =execute(request);;
			String str=response.body().string();
			JSONObject pa = JSONObject.parseObject(str);
			code=pa.getString("code");
		} catch (IOException e) {
			e.printStackTrace();
		}
		return code;
	}
	/**
	 *fast-gpt创建手动数据集
	 */
	public  String collectionCreate(String id,String name){
		JSONObject arrObj=new JSONObject();
		arrObj.put("datasetId",id);
		arrObj.put("parentId",null);
		arrObj.put("name",name);
		arrObj.put("type","virtual");
		arrObj.put("metadata",new JSONObject().put("test",111));
		System.out.println("输入参数："+arrObj);
		MediaType mediaType = MediaType.parse("application/json");
		RequestBody body = RequestBody.create(mediaType, arrObj.toString());
		Request request = new Request.Builder()
				.url(FAST_URL+"/core/dataset/collection/create")
				.method("POST", body)
				.addHeader("Content-Type", "application/json")
				.addHeader("Authorization","Bearer "+FAST_KEY)
				.build();
		String data="";
		try {
			Response response =execute(request);;
			String str=response.body().string();
			JSONObject pa = JSONObject.parseObject(str);
			String code=pa.getString("code");
			if(code.equals("200")){
				data=pa.getString("data");
				System.out.println(data);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return data;
	}
	/**
	 *fast-gpt创建文本数据集
	 */
    public  String createText(String id,String text,String name){
        JSONObject arrObj=new JSONObject();
		arrObj.put("text",text);
        arrObj.put("datasetId",id);
        arrObj.put("parentId",null);
        arrObj.put("name",name);
        arrObj.put("trainingType","qa");
        arrObj.put("chunkSize",8000);
		arrObj.put("chunkSplitter","");
		arrObj.put("qaPrompt","");
		arrObj.put("metadata",null);
        System.out.println("输入参数："+arrObj);
        MediaType mediaType = MediaType.parse("application/json");
        RequestBody body = RequestBody.create(mediaType, arrObj.toString());
        Request request = new Request.Builder()
                .url(FAST_URL+"/core/dataset/collection/create/text")
                .method("POST", body)
                .addHeader("Content-Type", "application/json")
                .addHeader("Authorization","Bearer "+FAST_KEY)
                .build();
        String data="";
        try {
            Response response =execute(request);;
            String str=response.body().string();
            JSONObject pa = JSONObject.parseObject(str);
            String code=pa.getString("code");
            if(code.equals("200")){
                data=pa.getString("data");
                System.out.println(data);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return data;
    }
	/**
	 *fast-gpt 获取知识训练  billId
	 */
	public String createTrainingUsage(String datasetId,String name){
		JSONObject arrObj=new JSONObject();
		arrObj.put("name",name);
		arrObj.put("datasetId",datasetId);
		System.out.println("输入参数："+arrObj);
		MediaType mediaType = MediaType.parse("application/json");
		RequestBody body = RequestBody.create(mediaType, arrObj.toString());
		Request request = new Request.Builder()
				.url(FAST_URL+"/support/wallet/usage/createTrainingUsage")
				.method("POST", body)
				.addHeader("Content-Type", "application/json")
				.addHeader("Token",getToken())
				.build();
		String data="";
		try {
			Response response =execute(request);;
			String str=response.body().string();
			JSONObject pa = JSONObject.parseObject(str);
			String code=pa.getString("code");
			if(code.equals("200")){
				data=pa.getString("data");
				System.out.println(data);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return data;
	}
	//上传文件获取 collectionId
	public String file(String datasetId){
		FormBody.Builder formBuilder = new FormBody.Builder();
		FileDataDto fileDataDto=new FileDataDto();
		fileDataDto.setTrainingType("chunk");
		fileDataDto.setDatasetId(datasetId);
		fileDataDto.setChunkSize(512);
		fileDataDto.setChunkSplitter("");
		fileDataDto.setQaPrompt("<Context></Context> 标记中是一段文本，学习和分析它，并整理学习成果： - 提出问题并给出每个问题的答案。 - 答案需详细完整，尽可能保留原文描述。 - 答案可以包含普通文字、链接、代码、表格、公示、媒体链接等 Markdown 元素。 - 最多提出 30 个问题。 ");
		fileDataDto.setName("template.csv");
		fileDataDto.setHashRawText("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
		fileDataDto.setRawTextLength(0);
		CollectionMetadata collectionMetadata=new CollectionMetadata();
		collectionMetadata.setRelatedImgId("I0HoNSxRjBYctAzguUz1klV5nvI4Df3N");
		fileDataDto.setCollectionMetadata(collectionMetadata);
		formBuilder.add("data", fileDataDto.toString());
		formBuilder.add("metadata", "{}");
		formBuilder.add("bucketName","dataset");
		formBuilder.add("file", "(binary)");
		RequestBody body = formBuilder.build();
		Request request = new Request.Builder()
				.url(FAST_URL+"/core/dataset/collection/create/file?datasetId="+datasetId)
				.method("POST", body)
				.addHeader("Content-Type", "multipart/form-data; boundary=----WebKitFormBoundary1P367OavBp8tripZ")
				.addHeader("Token",getToken())
				.build();
		String data="";
		try {
			Response response =execute(request);
			String str=response.body().string();
			JSONObject pa = JSONObject.parseObject(str);
			String code=pa.getString("code");
			if(code.equals("200")){
				data=pa.getString("data");
				System.out.println(data);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return data;
	}
	//上传数据
	public String pushData(String billId,String collectionId,List<DataDto> list){
		JSONObject arrObj=new JSONObject();
		arrObj.put("billId",billId);
		arrObj.put("collectionId",collectionId);
		arrObj.put("prompt","<Context></Context> 标记中是一段文本，学习和分析它，并整理学习成果：\\n- 提出问题并给出每个问题的答案。\\n- 答案需详细完整，尽可能保留原文描述。\\n- 答案可以包含普通文字、链接、代码、表格、公示、媒体链接等 Markdown 元素。\\n- 最多提出 30 个问题。\\n");
		arrObj.put("trainingMode","chunk");
		arrObj.put("data",list);
		System.out.println("输入参数："+arrObj);
		MediaType mediaType = MediaType.parse("application/json");
		RequestBody body = RequestBody.create(mediaType, arrObj.toString());
		Request request = new Request.Builder()
				.url(FAST_URL+"/core/dataset/data/pushData")
				.method("POST", body)
				.addHeader("Content-Type", "application/json")
				.addHeader("Token",getToken())
				.build();
		String data="";
		try {
			Response response =execute(request);;
			String str=response.body().string();
			JSONObject pa = JSONObject.parseObject(str);
			String code=pa.getString("code");
			if(code.equals("200")){
				data=pa.getString("data");
				System.out.println(data);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return data;
	}
	public static  String localFile(String id, String path){
		JSONObject arrObj=new JSONObject();
		arrObj.put("datasetId",id);
		arrObj.put("parentId",null);
		arrObj.put("trainingType","chunk");
		arrObj.put("chunkSize",512);
		arrObj.put("chunkSplitter","");
		arrObj.put("qaPrompt","");
		arrObj.put("metadata","{}");
		FormBody.Builder formBuilder = new FormBody.Builder();
		formBuilder.add("file", path);
		System.out.println(arrObj.toString());
		formBuilder.add("data", arrObj.toString());
		RequestBody body = formBuilder.build();
		Request request = new Request.Builder()
				.url(FAST_URL+"/core/dataset/collection/create/localFile")
				.post(body)
				.addHeader("Authorization","Bearer "+FAST_KEY)
				.build();
		String data="";
		try {
			Response response =execute(request);;
			String str=response.body().string();
			JSONObject pa = JSONObject.parseObject(str);
			String code=pa.getString("code");
			if(code.equals("200")){
				data=pa.getString("data");
				System.out.println(data);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return data;
	}
	/**
	 *fast-gpt获取数据集列表
	 */
	public  String dataSetList(String id, Integer pageNo,Integer pageSize,String searchText){
		JSONObject arrObj=new JSONObject();
		arrObj.put("datasetId",id);
		arrObj.put("pageNum",pageNo);
		arrObj.put("pageSize",pageSize);
		arrObj.put("parentId",null);
		arrObj.put("searchText",searchText);
		System.out.println("输入参数："+arrObj);
		MediaType mediaType = MediaType.parse("application/json");
		RequestBody body = RequestBody.create(mediaType, arrObj.toString());
		Request request = new Request.Builder()
				.url(FAST_URL+"/core/dataset/collection/list")
				.method("POST", body)
				.addHeader("Content-Type", "application/json")
				.addHeader("Authorization","Bearer "+FAST_KEY)
				.build();
		String data="";
		try {
			Response response =execute(request);;
			String str=response.body().string();
			JSONObject pa = JSONObject.parseObject(str);
			String code=pa.getString("code");
			if(code.equals("200")){
				data=pa.getString("data");
				System.out.println(data);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return data;
	}
	public  List<Object> pushData(String dataId,List<Map<String, Object>> maps){
		JSONObject arrObj=new JSONObject();
		arrObj.put("collectionId",dataId);
		arrObj.put("trainingMode", "chunk");
		List<DataDto> list=new ArrayList<>();
		maps.forEach(m->{
			DataDto dataDto=new DataDto();
			StringBuilder sb = new StringBuilder();
			m.forEach((key, value) -> {
				sb.append(key).append(":").append(value).append(",");
			});
			sb.append(";");
			dataDto.setQ(sb.toString());
			list.add(dataDto);
		});
		List<List<DataDto>> split = SplitListUtils.split(list, 200);
		 List<Object> list1= Lists.newArrayList();
		split.forEach(dataDtos -> {
			arrObj.put("data",dataDtos);
			System.out.println("输入参数："+arrObj);
			MediaType mediaType = MediaType.parse("application/json");
			RequestBody body = RequestBody.create(mediaType, arrObj.toString());
			Request request = new Request.Builder()
					.url(FAST_URL+"/core/dataset/data/pushData")
					.method("POST", body)
					.addHeader("Content-Type", "application/json")
					.addHeader("Authorization","Bearer "+FAST_KEY)
					.build();
			String data="";
			try {
				Response response =execute(request);;
				String str=response.body().string();
				JSONObject pa = JSONObject.parseObject(str);
				String code=pa.getString("code");
				if(code.equals("200")){
					data=pa.getString("data");
					System.out.println(data);
					list1.add("200");
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		});
		return list1;
	}
	/**
	 *fast-gpt获取数据列表
	 */
	public  String dataList(String collectionId, Integer pageNo,Integer pageSize,String searchText){
		JSONObject arrObj=new JSONObject();
		arrObj.put("collectionId",collectionId);
		arrObj.put("pageNum",pageNo);
		arrObj.put("pageSize",pageSize);
		arrObj.put("searchText",searchText);
		System.out.println("输入参数："+arrObj);
		MediaType mediaType = MediaType.parse("application/json");
		RequestBody body = RequestBody.create(mediaType, arrObj.toString());
		Request request = new Request.Builder()
				.url(FAST_URL+"/core/dataset/data/list")
				.method("POST", body)
				.addHeader("Content-Type", "application/json")
				.addHeader("Authorization","Bearer "+FAST_KEY)
				.build();
		String data="";
		try {
			Response response =execute(request);;
			String str=response.body().string();
			JSONObject pa = JSONObject.parseObject(str);
			String code=pa.getString("code");
			if(code.equals("200")){
				data=pa.getString("data");
				System.out.println(data);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return data;
	}
    public static Response execute(Request request) throws IOException {
        return HTTP_CLIENT.newCall(request).execute();
    }
    public Response asr(RequestBody body) throws IOException {
        Request request = new Request.Builder()
                .url(ASR_URL)
                .method("POST", body)
                .addHeader("Content-Type", "application/json")
                .build();
        return HTTP_CLIENT.newCall(request).execute();
    }
    public Response tts(RequestBody body) throws IOException {
        Request request = new Request.Builder()
                .url(TTS_URL)
                .method("POST", body)
                .addHeader("Content-Type", "application/json")
                .build();
        return HTTP_CLIENT.newCall(request).execute();
    }
    public  void inputStreamToFile(InputStream ins, File file) throws IOException {
        OutputStream os=null;
        try {
            os = new FileOutputStream(file);
            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            os.close();
            ins.close();
        }
    }
    private  File blobTransFile(String blob) throws IOException {
        File file = null;
        FileOutputStream fileOutputStream=null;
        InputStream inputStream=null;
        String filePath =System.currentTimeMillis()+".wav";
        try {
            URL url = new URL(blob);
            file=new File(filePath);
            inputStream = url.openStream();
            fileOutputStream = new FileOutputStream(file);
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                fileOutputStream.write(buffer, 0, bytesRead);
            }
            System.out.println("Blob file saved successfully!");
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            fileOutputStream.close();
            inputStream.close();
        }
        return file;
    }
    public static String convertDate(String strDate) {
        String str = "";
        try {
            String fmt = "yyyy-MM-dd HH:mm:ss";
            strDate = strDate.replace("T", " ");
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(fmt);
            return dateTimeFormatter.format(dateTimeFormatter.parse(strDate));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return str;
    }
    public  boolean isLocalImagePath(String path) {
        return  path.endsWith(".png")|| path.endsWith(".jpg");
    }
    public  boolean isLocalVideoPath(String path) {
        return  path.endsWith(".mp4")|| path.endsWith(".wav");
    }
    public static String generateHtml(String href) {
        return "<a href=\"" + href + "\"></a>";
    }
}
